<template>
  <div class="camera-capture">
    <!-- 返回按钮 - 左上角 -->
    <!-- <button class="router-back-btn" @click="handleBack">
      <img src="@/assets/routerback.png" alt="返回" />
    </button> -->

    <!-- 左侧区域：拍照模式选择 + 中间摄像头区域 -->
    <div class="camera-left-section">
      <!-- 中间摄像头区域 - 居中显示 -->
      <div class="camera-center">
        <!-- 摄像头预览区域 -->
        <div class="camera-preview-area">
          <div class="camera-frame" ref="cameraFrameRef">
            <!-- 实时摄像头预览或静态图片 -->
            <video v-if="cameraAvailable && cameraStream && !showStaticImage" ref="videoRef" :srcObject="cameraStream" autoplay muted
              playsinline class="camera-video" />

            <!-- 拍照后的静态图片 -->
            <img v-else-if="showStaticImage && currentCapturedImage" :src="currentCapturedImage"
              class="camera-video static-image" alt="拍摄的图片" />

            <!-- 无摄像头时的提示信息 -->
            <div v-else class="no-camera-message">
              <div class="message-content">
                <div class="camera-icon">📷</div>
                <h3>无法访问摄像头</h3>
                <p>请确保已允许浏览器访问摄像头权限</p>
                <p>或检查摄像头设备是否正常连接</p>
              </div>
            </div>

            <!-- 拍照后的灰色蒙版和裁切框 -->
            <div v-if="showCropOverlay" class="crop-overlay">
              <div class="crop-mask" :style="cropMaskStyle"></div>
              <div class="crop-frame" :style="cropFrameStyle" @mousedown="handleCropFrameMouseDown">
                <div class="crop-corner crop-corner-tl" @mousedown.stop="handleCornerMouseDown('tl', $event)"></div>
                <div class="crop-corner crop-corner-tr" @mousedown.stop="handleCornerMouseDown('tr', $event)"></div>
                <div class="crop-corner crop-corner-bl" @mousedown.stop="handleCornerMouseDown('bl', $event)"></div>
                <div class="crop-corner crop-corner-br" @mousedown.stop="handleCornerMouseDown('br', $event)"></div>

                <!-- 裁切确认按钮 -->
                <div class="crop-actions">
                  <button class="crop-btn crop-cancel" @click="handleCropCancel">
                    <span>✕</span>
                  </button>
                  <button class="crop-btn crop-confirm" @click="handleCropConfirm">
                    <span>✓</span>
                  </button>
                </div>
              </div>

              <!-- 裁切提示文字 -->
              <div class="crop-hint">
                <span>拖拽调整裁切区域</span>
              </div>
            </div>

            <!-- 拍照辅助线 -->
            <div v-if="showGuideLines" class="guide-lines">
              <div class="guide-line guide-line-h1"></div>
              <div class="guide-line guide-line-h2"></div>
              <div class="guide-line guide-line-v1"></div>
              <div class="guide-line guide-line-v2"></div>
            </div>
          </div>
        </div>

        <!-- 左侧拍照模式选择 - 绝对定位到摄像头区域左侧 -->
        <div class="camera-sidebar">
          <div class="capture-modes">
            <div class="mode-item" :class="{ active: captureMode === 'single' }" @click="setCaptureMode('single')">
              <div class="mode-icon">
                <img src="@/assets/document.png" alt="单页拍照" />
              </div>
              <span class="mode-text">单页拍照</span>
            </div>

            <div class="mode-item" :class="{ active: captureMode === 'full' }" @click="setCaptureMode('full')">
              <div class="mode-icon">
                <img src="@/assets/document.png" alt="整页拍照" />
              </div>
              <span class="mode-text">整页拍照</span>
            </div>
          </div>
        </div>

        <!-- 底部控制按钮 - 绝对定位到摄像头区域下方 -->
        <div class="camera-controls">
          <button class="control-btn back-btn" @click="handleBack">
            <img src="@/assets/complete.png" alt="返回" />
            <span>返回</span>
          </button>

          <button class="control-btn capture-btn"
                  :class="{ capturing: isCapturing, disabled: !cameraAvailable }"
                  :disabled="!cameraAvailable"
                  @click="handleCapture">
            <div class="capture-circle">
              <div class="capture-inner"></div>
            </div>
          </button>

          <button class="control-btn import-btn" @click="handleImport">
            <img src="@/assets/complete.png" alt="文件导入" />
            <span>文件导入</span>
          </button>
        </div>
      </div>
    </div>

    <!-- 右侧预览区域（仅在有照片时显示） - 相对定位覆盖层 -->
    <div v-if="capturedPhotos.length > 0" class="preview-sidebar">
      <div class="preview-list">
        <!-- 已拍摄的照片预览 -->
        <div v-for="(photo, index) in capturedPhotos" :key="index" class="preview-item"
          :class="{ active: selectedPreview === index }" @click="handlePreviewClick(index)">
          <!-- 蓝色序号标签 - 左上角 -->
          <div class="preview-number">{{ index + 1 }}</div>
          <!-- 灰色删除按钮 - 右上角 -->
          <div class="preview-delete" @click.stop="handleDeletePhoto(index)">
            <span>✕</span>
          </div>
          <div class="preview-image">
            <img v-if="photo.thumbnail" :src="photo.thumbnail" :alt="`第${index + 1}页`" />
            <!-- 模拟白纸预览 -->
            <div v-else class="paper-thumbnail">
              <div class="thumbnail-content">
                <div class="thumbnail-header">试卷{{ index + 1 }}</div>
                <div class="thumbnail-lines">
                  <div class="line"></div>
                  <div class="line"></div>
                  <div class="line"></div>
                  <div class="line"></div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 添加更多按钮 -->
        <div class="add-more-btn"
             :class="{ disabled: !cameraAvailable }"
             @click="cameraAvailable ? handleCapture() : null">
          <div class="add-icon">+</div>
          <span>{{ cameraAvailable ? '继续拍照' : '导入文件' }}</span>
        </div>

        <!-- 完成按钮 -->
        <div class="complete-btn" @click="handleComplete">
          <span>完成</span>
        </div>
      </div>
    </div>

    <!-- PC端文件导入弹窗 -->
    <el-dialog v-model="showFileImportDialog" title="文件导入" width="500px" :show-close="true"
      @close="showFileImportDialog = false">
      <div class="file-import-dialog">
        <div class="upload-file-section">
          <div class="upload-file-label">* 上传文件</div>
          <div class="upload-file-area">
            <el-upload ref="dialogUploadRef" :file-list="dialogFileList" :before-upload="beforeUpload"
              :on-change="handleDialogFileChange" :auto-upload="false" multiple drag accept="image/*,.pdf">
              <div class="upload-file-content">
                <el-icon size="48" class="upload-file-icon">
                  <Document />
                </el-icon>
                <div class="upload-file-text">
                  <div class="upload-main-text">点击或将文件拖拽到此区域上传</div>
                  <div class="upload-sub-text">支持图片和PDF格式，单个文件不超过10MB</div>
                </div>
              </div>
            </el-upload>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showFileImportDialog = false">取消</el-button>
          <el-button type="primary" @click="handleFileImportConfirm">确认</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Document } from '@element-plus/icons-vue'
import type { UploadFile } from 'element-plus'
import { photoStorage, type PhotoData } from '@/utils/indexedDB'
import { t as $t } from '@/plugins/i18nPlugin'

// Props
interface Props {
  userType?: 'teacher' | 'student'
  fromRoute?: string // 来源路由名称
  context?: string // 上下文信息，如 'task-creation'
  taskName?: string // 任务名称
}

const props = withDefaults(defineProps<Props>(), {
  userType: 'teacher',
  context: '',
  taskName: '教学任务'
})

// Router
const router = useRouter()
const route = useRoute()

// Emits
const emit = defineEmits<{
  back: []
  capture: [photos: CapturedPhoto[]]
  complete: [photos: CapturedPhoto[]]
  preview: [data: { photos: CapturedPhoto[], currentIndex: number, taskName: string }]
  import: []
}>()

// 接口定义
interface CapturedPhoto {
  id: string
  thumbnail: string
  fullImage: string
  timestamp: number
  processed?: boolean
}

// 响应式数据
const captureMode = ref<'single' | 'full'>('single')
const isCapturing = ref(false)
const selectedPreview = ref(0)
const capturedPhotos = ref<CapturedPhoto[]>([]) // 初始为空，等待用户拍照或导入
const showFileImportDialog = ref(false)

// 摄像头相关
const cameraStream = ref<MediaStream | null>(null)
const videoRef = ref<HTMLVideoElement>()
const cameraFrameRef = ref<HTMLDivElement>()
const canvasRef = ref<HTMLCanvasElement>()
const cameraAvailable = ref(false) // 摄像头是否可用

// 裁切相关
const showCropOverlay = ref(false)
const showGuideLines = ref(true)
const showStaticImage = ref(false)
const cropFrame = ref({
  x: 50,
  y: 50,
  width: 300,
  height: 200
})

// 拖拽相关状态
const isDragging = ref(false)
const isResizing = ref(false)
const dragStart = ref({ x: 0, y: 0 })
const resizeCorner = ref('')

// 计算裁切框样式
const cropFrameStyle = computed(() => ({
  left: `${cropFrame.value.x}px`,
  top: `${cropFrame.value.y}px`,
  width: `${cropFrame.value.width}px`,
  height: `${cropFrame.value.height}px`
}))

// 计算裁切蒙版的CSS变量
const cropMaskStyle = computed(() => {
  if (!cameraFrameRef.value) return {}

  const frameRect = cameraFrameRef.value.getBoundingClientRect()
  const leftPercent = (cropFrame.value.x / frameRect.width) * 100
  const topPercent = (cropFrame.value.y / frameRect.height) * 100
  const rightPercent = ((cropFrame.value.x + cropFrame.value.width) / frameRect.width) * 100
  const bottomPercent = ((cropFrame.value.y + cropFrame.value.height) / frameRect.height) * 100

  return {
    '--crop-left': `${leftPercent}%`,
    '--crop-top': `${topPercent}%`,
    '--crop-right': `${rightPercent}%`,
    '--crop-bottom': `${bottomPercent}%`
  }
})

// 方法
const setCaptureMode = (mode: 'single' | 'full') => {
  captureMode.value = mode
  const modeText = mode === 'single' ? '单页拍照' : '整页拍照'
  ElMessage.info(`切换到${modeText}模式`)
}

const handleBack = () => {
  // 停止摄像头
  stopCamera()

  // 获取返回路由信息
  const returnTo = route.query.returnTo as string
  const fromRoute = props.fromRoute || route.query.fromRoute as string

  // 根据来源决定返回路径
  if (returnTo) {
    // 如果有明确的返回路径，直接跳转
    router.push({ name: returnTo })
  } else if (fromRoute) {
    // 根据来源路由决定返回路径
    switch (fromRoute) {
      case 'create-task-wizard':
        router.push({ name: 'create-task-wizard' })
        break
      case 'homework-submission-detail':
        router.push({ name: 'homework-submission-detail', params: route.params })
        break
      case 'task-detail':
        router.push({ name: 'task-detail', params: route.params })
        break
      case 'grading-history':
        router.push({ name: 'grading-history' })
        break
      default:
        // 默认返回上一页
        router.go(-1)
    }
  } else {
    // 没有明确路由信息时，返回上一页
    router.go(-1)
  }

  emit('back')
}

const handleCapture = async () => {
  if (isCapturing.value) return

  // 如果摄像头不可用，提示用户使用文件导入
  if (!cameraAvailable.value) {
    ElMessage.warning('摄像头不可用，请使用文件导入功能')
    handleImport()
    return
  }

  isCapturing.value = true
  showGuideLines.value = false

  try {
    let imageData: string

    if (cameraStream.value && videoRef.value) {
      // 从摄像头捕获图像
      imageData = await captureFromCamera()
    } else {
      // 模拟拍照（使用模拟图片）
      imageData = await simulateCapture()
    }

    // 暂存当前拍摄的图片
    currentCapturedImage.value = imageData

    // 冻结摄像头画面 - 停止视频流显示
    if (cameraStream.value) {
      // 暂时隐藏视频，显示静态图片
      showStaticImage.value = true
    }

    // 显示裁切界面
    showCropOverlay.value = true

  } catch (error) {
    ElMessage.error('拍照失败，请重试')
    console.error('Capture error:', error)
  } finally {
    isCapturing.value = false
  }
}

// 从摄像头捕获图像
const captureFromCamera = async (): Promise<string> => {
  return new Promise((resolve, reject) => {
    if (!videoRef.value || !cameraFrameRef.value) {
      reject(new Error('Camera not ready'))
      return
    }

    // 创建canvas来捕获视频帧
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')

    if (!ctx) {
      reject(new Error('Canvas context not available'))
      return
    }

    // 设置canvas尺寸与视频相同
    canvas.width = videoRef.value.videoWidth
    canvas.height = videoRef.value.videoHeight

    // 绘制当前视频帧到canvas
    ctx.drawImage(videoRef.value, 0, 0, canvas.width, canvas.height)

    // 转换为base64图片数据
    const imageData = canvas.toDataURL('image/jpeg', 0.9)
    resolve(imageData)
  })
}

// 模拟拍照（用于演示）
const simulateCapture = async (): Promise<string> => {
  // 模拟拍照延迟
  await new Promise(resolve => setTimeout(resolve, 300))

  // 返回模拟的图片数据（实际应用中这里会是真实的图片）
  return ''
}

// 当前拍摄的图片数据
const currentCapturedImage = ref<string>('')

// 处理裁切取消
const handleCropCancel = () => {
  showCropOverlay.value = false
  showGuideLines.value = true
  showStaticImage.value = false
  currentCapturedImage.value = ''
  ElMessage.info('已取消裁切')
}

// 处理裁切确认 - 实际裁切图片
const handleCropConfirm = async () => {
  if (!currentCapturedImage.value || !cameraFrameRef.value) return

  try {
    // 获取摄像头框架的实际尺寸
    const frameRect = cameraFrameRef.value.getBoundingClientRect()

    // 计算裁切区域相对于图片的比例
    const cropRatio = {
      x: cropFrame.value.x / frameRect.width,
      y: cropFrame.value.y / frameRect.height,
      width: cropFrame.value.width / frameRect.width,
      height: cropFrame.value.height / frameRect.height
    }

    // 执行实际裁切
    const croppedImage = await cropImage(currentCapturedImage.value, cropRatio)
    const processedImage = await processImage(croppedImage)

    // 创建新的照片对象
    const newPhoto: CapturedPhoto = {
      id: `photo_${Date.now()}`,
      thumbnail: await generateThumbnail(processedImage),
      fullImage: processedImage,
      timestamp: Date.now(),
      processed: true
    }

    // 添加到照片列表
    capturedPhotos.value.push(newPhoto)
    selectedPreview.value = capturedPhotos.value.length - 1

    // 重置状态并恢复摄像头
    showCropOverlay.value = false
    showGuideLines.value = true
    showStaticImage.value = false
    currentCapturedImage.value = ''

    // 确保摄像头视频流正常显示
    if (cameraStream.value && videoRef.value) {
      videoRef.value.srcObject = cameraStream.value
    }

    ElMessage.success(`拍照成功，已拍摄${capturedPhotos.value.length}张照片`)
  } catch (error) {
    ElMessage.error('图片处理失败，请重试')
    console.error('Image processing error:', error)
  }
}

// 实际裁切图片函数
const cropImage = async (imageData: string, cropRatio: { x: number, y: number, width: number, height: number }): Promise<string> => {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')

      if (!ctx) {
        resolve(imageData)
        return
      }

      // 计算实际裁切区域
      const cropX = img.width * cropRatio.x
      const cropY = img.height * cropRatio.y
      const cropWidth = img.width * cropRatio.width
      const cropHeight = img.height * cropRatio.height

      // 设置canvas尺寸为裁切区域大小
      canvas.width = cropWidth
      canvas.height = cropHeight

      // 绘制裁切后的图片
      ctx.drawImage(
        img,
        cropX, cropY, cropWidth, cropHeight,  // 源图片裁切区域
        0, 0, cropWidth, cropHeight           // 目标canvas区域
      )

      resolve(canvas.toDataURL('image/jpeg', 0.9))
    }
    img.src = imageData
  })
}

// 图像处理（智能增强）
const processImage = async (imageData: string): Promise<string> => {
  // 这里应该实现图像处理逻辑：
  // 1. 透视校正
  // 2. 去阴影和反光
  // 3. 增强对比度
  // 4. 转换为白底黑字

  // 目前返回原图，实际应用中需要调用图像处理API
  return imageData
}

// 生成缩略图
const generateThumbnail = async (imageData: string): Promise<string> => {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')

      if (!ctx) {
        resolve(imageData)
        return
      }

      // 设置缩略图尺寸
      const maxSize = 120
      const ratio = Math.min(maxSize / img.width, maxSize / img.height)
      canvas.width = img.width * ratio
      canvas.height = img.height * ratio

      // 绘制缩略图
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
      resolve(canvas.toDataURL('image/jpeg', 0.8))
    }
    img.src = imageData
  })
}

const handleImport = () => {
  // 检测设备类型
  const isIPad = /iPad|iPhone|iPod/.test(navigator.userAgent) ||
    (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)

  if (isIPad) {
    // iPad端：调用设备相册
    openPhotoAlbum()
  } else {
    // PC端：显示文件导入弹窗
    showFileImportDialog.value = true
  }
}

const openPhotoAlbum = () => {
  // 创建隐藏的文件输入元素来访问相册
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = 'image/*'
  input.multiple = true
  input.capture = 'environment' // 优先使用后置摄像头

  input.onchange = (event: Event) => {
    const target = event.target as HTMLInputElement
    const files = target.files
    if (files && files.length > 0) {
      handlePhotoImport(Array.from(files))
    }
  }

  input.click()
}

const handlePhotoImport = async (files: File[]) => {
  // 处理从相册导入的照片
  for (let i = 0; i < files.length; i++) {
    const file = files[i]
    try {
      const imageData = await fileToBase64(file)
      const processedImage = await processImage(imageData)

      const newPhoto: CapturedPhoto = {
        id: `imported_${Date.now()}_${i}`,
        thumbnail: await generateThumbnail(processedImage),
        fullImage: processedImage,
        timestamp: Date.now(),
        processed: true
      }

      capturedPhotos.value.push(newPhoto)
    } catch (error) {
      console.error('Error processing imported file:', error)
    }
  }

  ElMessage.success(`导入成功，已导入${files.length}个文件`)
}

// 文件转Base64
const fileToBase64 = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => resolve(reader.result as string)
    reader.onerror = reject
    reader.readAsDataURL(file)
  })
}

const handleFileImportConfirm = async () => {
  // PC端文件导入确认
  if (dialogFileList.value.length === 0) {
    ElMessage.warning('请选择要导入的文件')
    return
  }

  try {
    // 处理选中的文件
    for (let i = 0; i < dialogFileList.value.length; i++) {
      const uploadFile = dialogFileList.value[i]
      if (uploadFile.raw) {
        const imageData = await fileToBase64(uploadFile.raw)
        const processedImage = await processImage(imageData)

        const newPhoto: CapturedPhoto = {
          id: `imported_${Date.now()}_${i}`,
          thumbnail: await generateThumbnail(processedImage),
          fullImage: processedImage,
          timestamp: Date.now(),
          processed: true
        }

        capturedPhotos.value.push(newPhoto)
      }
    }

    // 记录导入数量
    const importCount = dialogFileList.value.length

    // 清空文件列表并关闭弹窗
    dialogFileList.value = []
    showFileImportDialog.value = false

    ElMessage.success(`导入成功，已导入${importCount}个文件`)
  } catch (error) {
    ElMessage.error('文件导入失败，请重试')
    console.error('File import error:', error)
  }
}

const selectPreview = (index: number) => {
  selectedPreview.value = index
}

const handlePreviewClick = (index: number) => {
  // 只选中当前照片，不触发预览事件
  selectedPreview.value = index
}

const handleDeletePhoto = (index: number) => {
  // 删除指定索引的照片
  capturedPhotos.value.splice(index, 1)

  // 调整选中的预览索引
  if (selectedPreview.value >= capturedPhotos.value.length) {
    selectedPreview.value = Math.max(0, capturedPhotos.value.length - 1)
  }

  ElMessage.success('删除成功')
}

const handleComplete = async () => {
  if (capturedPhotos.value.length === 0) {
    ElMessage.warning('请先拍摄或导入照片')
    return
  }

  try {
    // 获取上下文信息（优先使用 props，然后是 route.query）
    const context = props.context || route.query.context as string
    const taskName = props.taskName || route.query.taskName as string || '教学任务'
    const taskId = route.query.taskId as string
    const studentId = route.query.studentId as string
    const returnTo = route.query.returnTo as string || ''

    console.log('CameraCapture完成拍照，上下文信息:', {
      context,
      taskName,
      taskId,
      studentId,
      returnTo,
      photosCount: capturedPhotos.value.length,
      propsContext: props.context,
      propsTaskName: props.taskName
    })

    // 导入photos数据库
    const { photosStorage } = await import('@/utils/photosDB')
    await photosStorage.init()

    // 根据上下文决定isCreate的值
    const isCreate = context === 'task-creation'
    
    // 转换照片数据格式为IndexedDB格式
    const photosForStorage = capturedPhotos.value.map(photo => ({
      id: photo.id,
      taskId: taskId || `temp-${Date.now()}`, // 临时任务ID，后续会更新
      studentId: studentId || undefined,
      isCreate: isCreate, // 创建任务时为true，学生作业上传时为false
      thumbnail: photo.thumbnail,
      fullImage: photo.fullImage,
      timestamp: photo.timestamp,
      teacherID: 'teacher-001', // 当前教师ID
      fileName: `照片${Date.now()}.jpg`,
      fileSize: '32.2KB',
      description: isCreate ? '教学任务试卷图片' : '学生作业图片'
    }))

    // 保存照片到photos数据库
    await photosStorage.savePhotos(photosForStorage)
    console.log('照片已保存到photos数据库:', photosForStorage.length, '张')

    // 停止摄像头
    stopCamera()

    // 根据上下文决定跳转逻辑
    if (context === 'task-detail-edit' && returnTo === 'task-detail') {
      // 从任务详情页面的学生作业上传来的，直接返回任务详情页面
      ElMessage.success('学生作业照片已保存')
      
      // 同时保存到studentPhotos数据库
      try {
        const { studentPhotosStorage } = await import('@/utils/studentPhotosDB')
        await studentPhotosStorage.init()
        
        const studentPhotosForStorage = photosForStorage
          .filter(photo => photo.studentId) // 只处理有studentId的照片
          .map(photo => ({
            id: `student-${photo.id}`,
            taskId: photo.taskId,
            studentId: photo.studentId!,
            thumbnail: photo.thumbnail,
            fullImage: photo.fullImage,
            timestamp: photo.timestamp,
            teacherID: photo.teacherID,
            fileName: photo.fileName,
            fileSize: photo.fileSize,
            description: photo.description,
            status: 'pending' as const
          }))
        
        if (studentPhotosForStorage.length > 0) {
          await studentPhotosStorage.saveStudentPhotos(studentPhotosForStorage)
          console.log('学生照片已保存到studentPhotos数据库:', studentPhotosForStorage.length, '张')
        }
      } catch (error) {
        console.error('保存学生照片到studentPhotos数据库失败:', error)
      }
      
      router.push({
        name: 'task-detail',
        params: {
          id: taskId
        },
        query: {
          fromCameraCapture: 'true',
          studentId: studentId,
          photoUpdated: 'true'
        }
      })
    } else if (context === 'homework-grading-detail' && returnTo === 'homework-submission-detail') {
      // 从作业批改详情页面添加照片，返回批改详情页面
      ElMessage.success('新照片已添加')
      
      // 同时保存到studentPhotos数据库
      try {
        const { studentPhotosStorage } = await import('@/utils/studentPhotosDB')
        await studentPhotosStorage.init()
        
        const studentPhotosForStorage = photosForStorage
          .filter(photo => photo.studentId) // 只处理有studentId的照片
          .map(photo => ({
            id: `student-${photo.id}`,
            taskId: photo.taskId,
            studentId: photo.studentId!,
            thumbnail: photo.thumbnail,
            fullImage: photo.fullImage,
            timestamp: photo.timestamp,
            teacherID: photo.teacherID,
            fileName: photo.fileName,
            fileSize: photo.fileSize,
            description: photo.description,
            status: 'pending' as const
          }))
        
        if (studentPhotosForStorage.length > 0) {
          await studentPhotosStorage.saveStudentPhotos(studentPhotosForStorage)
          console.log('学生照片已保存到studentPhotos数据库:', studentPhotosForStorage.length, '张')
        }
      } catch (error) {
        console.error('保存学生照片到studentPhotos数据库失败:', error)
      }
      
      router.push({
        name: 'homework-submission-detail',
        params: {
          taskId: taskId
        },
        query: {
          studentId: studentId,
          studentName: route.query.studentName,
          taskName: taskName,
          fromCameraCapture: 'true',
          photoAdded: 'true'
        }
      })
    } else if (context === 'task-creation' || returnTo === 'task-creation-wizard') {
      // 任务创建流程，跳转到照片预览页面
      console.log('跳转到照片预览页面，传递任务信息')

      // 获取现有的照片数据
      const existingPhotosDataStr = localStorage.getItem('currentSessionPhotosData')
      let existingPhotosData = []
      if (existingPhotosDataStr) {
        try {
          existingPhotosData = JSON.parse(existingPhotosDataStr)
          console.log('CameraCapture: 发现现有照片数据:', existingPhotosData.length, '张')
        } catch (e) {
          console.log('CameraCapture: 解析现有照片数据失败:', e)
          existingPhotosData = []
        }
      }

      // 获取当前拍摄会话的照片数据
      const newPhotosData = capturedPhotos.value.map(photo => ({
        id: photo.id,
        thumbnail: photo.thumbnail,
        fullImage: photo.fullImage,
        timestamp: photo.timestamp
      }))

      // 合并现有照片和新照片，去重（基于ID）
      const allPhotosData = [...existingPhotosData]
      newPhotosData.forEach(newPhoto => {
        const existingIndex = allPhotosData.findIndex(existing => existing.id === newPhoto.id)
        if (existingIndex === -1) {
          // 新照片，添加到列表
          allPhotosData.push(newPhoto)
          console.log('CameraCapture: 添加新照片 ID:', newPhoto.id)
        } else {
          // 已存在的照片，更新数据
          allPhotosData[existingIndex] = newPhoto
          console.log('CameraCapture: 更新现有照片 ID:', newPhoto.id)
        }
      })

      // 按时间戳排序，确保最新的照片在前面
      const sortedPhotosData = allPhotosData.sort((a, b) => b.timestamp - a.timestamp)
      const allPhotoIds = sortedPhotosData.map(photo => photo.id)

      console.log('CameraCapture: 准备存储照片数据到 localStorage:', {
        existingPhotosCount: existingPhotosData.length,
        newPhotosCount: newPhotosData.length,
        totalPhotosCount: sortedPhotosData.length,
        photoIds: allPhotoIds,
        photosData: sortedPhotosData
      })

      // 将合并后的照片数据存储到 localStorage
      localStorage.setItem('currentSessionPhotoIds', JSON.stringify(allPhotoIds))
      localStorage.setItem('currentSessionPhotosData', JSON.stringify(sortedPhotosData))

      // 验证存储是否成功
      const storedData = localStorage.getItem('currentSessionPhotosData')
      console.log('CameraCapture: 验证 localStorage 存储:', {
        stored: !!storedData,
        storedLength: storedData ? JSON.parse(storedData).length : 0
      })

      console.log('CameraCapture: 已将照片数据存储到 localStorage:', sortedPhotosData.length, '张照片')

      router.push({
        name: 'photo-preview',
        query: {
          currentIndex: selectedPreview.value.toString(),
          taskName: taskName,
          context: context || 'task-creation',
          taskId: taskId,
          studentId: studentId,
          fromRoute: 'create-task-wizard',
          sessionPhotoIds: JSON.stringify(allPhotoIds)
        }
      })
    } else {
      // 根据来源路由决定跳转目标
      if (props.fromRoute === 'homework-submission-detail') {
        // 题目详情的"再拍一张" -> PhotoPreview -> 返回原页面
        router.push({
          name: 'photo-preview',
          query: {
            currentIndex: selectedPreview.value.toString(),
            taskName: taskName,
            context: context,
            taskId: taskId,
            studentId: studentId,
            fromRoute: props.fromRoute,
            returnTo: 'grading-history'
          }
        })
      } else {
        // 其他情况，默认跳转到照片预览页面
        router.push({
          name: 'photo-preview',
          query: {
            currentIndex: selectedPreview.value.toString(),
            taskName: taskName,
            context: context,
            taskId: taskId,
            studentId: studentId,
            fromRoute: props.fromRoute || 'default'
          }
        })
      }
    }

    // 触发完成事件
    emit('capture', capturedPhotos.value)
    emit('complete', capturedPhotos.value)
    ElMessage.success(`保存成功，已保存${photosForStorage.length}张照片`)
  } catch (error) {
    console.error('保存照片失败:', error)
    ElMessage.error('保存失败，请重试')
  }
}

// 摄像头初始化和控制
const initCamera = async () => {
  try {
    // 检查浏览器是否支持摄像头
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      throw new Error('浏览器不支持摄像头功能')
    }

    // 检查是否有可用的摄像头设备
    const devices = await navigator.mediaDevices.enumerateDevices()
    const videoDevices = devices.filter(device => device.kind === 'videoinput')

    if (videoDevices.length === 0) {
      throw new Error('未检测到摄像头设备')
    }

    const stream = await navigator.mediaDevices.getUserMedia({
      video: {
        facingMode: 'environment', // 优先使用后置摄像头
        width: { ideal: 1920 },
        height: { ideal: 1080 }
      }
    })

    cameraStream.value = stream
    cameraAvailable.value = true

    // 等待video元素准备就绪
    if (videoRef.value) {
      videoRef.value.srcObject = stream
    }

    console.log('摄像头初始化成功')
    // 在开发环境下不显示成功消息，避免干扰
    if (import.meta.env.DEV) {
      console.log('开发模式：摄像头已启动')
    } else {
      ElMessage.success('摄像头已启动')
    }
  } catch (error) {
    console.warn('摄像头初始化失败:', error)

    // 根据错误类型提供不同的提示
    let errorMessage = '无法访问摄像头'
    if (error instanceof Error) {
      if (error.name === 'NotFoundError' || error.message.includes('未检测到摄像头')) {
        errorMessage = '未检测到摄像头设备，您可以使用上传功能'
      } else if (error.name === 'NotAllowedError') {
        errorMessage = '摄像头权限被拒绝，请允许访问摄像头或使用上传功能'
      } else if (error.name === 'NotReadableError') {
        errorMessage = '摄像头被其他应用占用，请关闭其他应用或使用上传功能'
      }
    }

    // 在开发环境下使用console.warn而不是弹窗提示
    if (import.meta.env.DEV) {
      console.warn('开发模式：' + errorMessage)
    } else {
      ElMessage.warning(errorMessage)
    }
  }
}

const stopCamera = () => {
  if (cameraStream.value) {
    cameraStream.value.getTracks().forEach(track => track.stop())
    cameraStream.value = null
  }
}

// 文件导入相关变量和方法
const dialogUploadRef = ref()
const dialogFileList = ref<UploadFile[]>([])

const beforeUpload = (file: File) => {
  const isValidType = ['image/jpeg', 'image/png', 'application/pdf'].includes(file.type)
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isValidType) {
    ElMessage.error('只能上传 JPG/PNG/PDF 格式的文件!')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('上传文件大小不能超过 10MB!')
    return false
  }
  return false // 阻止自动上传
}

const handleDialogFileChange = (file: UploadFile, fileList: UploadFile[]) => {
  dialogFileList.value = fileList
}

// 移除重复的onMounted，合并到下面的onMounted中

// 裁切框拖拽功能
const handleCropFrameMouseDown = (event: MouseEvent) => {
  isDragging.value = true
  dragStart.value = {
    x: event.clientX - cropFrame.value.x,
    y: event.clientY - cropFrame.value.y
  }

  document.addEventListener('mousemove', handleCropFrameMouseMove)
  document.addEventListener('mouseup', handleCropFrameMouseUp)
  event.preventDefault()
}

const handleCropFrameMouseMove = (event: MouseEvent) => {
  if (!isDragging.value && !isResizing.value) return

  if (isDragging.value) {
    // 拖拽移动裁切框
    const newX = event.clientX - dragStart.value.x
    const newY = event.clientY - dragStart.value.y

    // 限制在摄像头区域内
    if (cameraFrameRef.value) {
      const frameRect = cameraFrameRef.value.getBoundingClientRect()
      const maxX = frameRect.width - cropFrame.value.width
      const maxY = frameRect.height - cropFrame.value.height

      cropFrame.value.x = Math.max(0, Math.min(newX, maxX))
      cropFrame.value.y = Math.max(0, Math.min(newY, maxY))
    }
  } else if (isResizing.value) {
    // 调整裁切框大小
    handleResize(event)
  }
}

const handleCropFrameMouseUp = () => {
  isDragging.value = false
  isResizing.value = false
  resizeCorner.value = ''

  document.removeEventListener('mousemove', handleCropFrameMouseMove)
  document.removeEventListener('mouseup', handleCropFrameMouseUp)
}

const handleCornerMouseDown = (corner: string, event: MouseEvent) => {
  isResizing.value = true
  resizeCorner.value = corner
  dragStart.value = { x: event.clientX, y: event.clientY }

  document.addEventListener('mousemove', handleCropFrameMouseMove)
  document.addEventListener('mouseup', handleCropFrameMouseUp)
  event.preventDefault()
}

const handleResize = (event: MouseEvent) => {
  if (!cameraFrameRef.value) return

  const frameRect = cameraFrameRef.value.getBoundingClientRect()
  const deltaX = event.clientX - dragStart.value.x
  const deltaY = event.clientY - dragStart.value.y

  const minSize = 50 // 最小裁切框尺寸

  switch (resizeCorner.value) {
    case 'tl': // 左上角
      cropFrame.value.x = Math.max(0, cropFrame.value.x + deltaX)
      cropFrame.value.y = Math.max(0, cropFrame.value.y + deltaY)
      cropFrame.value.width = Math.max(minSize, cropFrame.value.width - deltaX)
      cropFrame.value.height = Math.max(minSize, cropFrame.value.height - deltaY)
      break
    case 'tr': // 右上角
      cropFrame.value.y = Math.max(0, cropFrame.value.y + deltaY)
      cropFrame.value.width = Math.max(minSize, Math.min(frameRect.width - cropFrame.value.x, cropFrame.value.width + deltaX))
      cropFrame.value.height = Math.max(minSize, cropFrame.value.height - deltaY)
      break
    case 'bl': // 左下角
      cropFrame.value.x = Math.max(0, cropFrame.value.x + deltaX)
      cropFrame.value.width = Math.max(minSize, cropFrame.value.width - deltaX)
      cropFrame.value.height = Math.max(minSize, Math.min(frameRect.height - cropFrame.value.y, cropFrame.value.height + deltaY))
      break
    case 'br': // 右下角
      cropFrame.value.width = Math.max(minSize, Math.min(frameRect.width - cropFrame.value.x, cropFrame.value.width + deltaX))
      cropFrame.value.height = Math.max(minSize, Math.min(frameRect.height - cropFrame.value.y, cropFrame.value.height + deltaY))
      break
  }

  dragStart.value = { x: event.clientX, y: event.clientY }
}

onMounted(async () => {
  // 只在新的拍照会话时清空数据，如果是从PhotoPreview返回则不清空
  const returnTo = route.query.returnTo as string
  if (returnTo !== 'photo-preview') {
    console.log('CameraCapture 初始化：清空之前的图片数据（新会话）')
    localStorage.removeItem('capturedPhotosData')
    localStorage.removeItem('currentSessionPhotoIds')
    localStorage.removeItem('currentSessionPhotosData')
    capturedPhotos.value = []
  } else {
    console.log('CameraCapture 初始化：从PhotoPreview返回，保留现有数据')
  }

  // 初始化摄像头
  initCamera()

  // 如果是从PhotoPreview返回，加载现有照片
  if (route.query.returnTo === 'photo-preview') {
    try {
      const existingPhotos = await photoStorage.getPhotos()
      if (existingPhotos && existingPhotos.length > 0) {
        // 将IndexedDB中的照片转换为CapturedPhoto格式
        capturedPhotos.value = existingPhotos.map(photo => ({
          id: photo.id,
          thumbnail: photo.thumbnail,
          fullImage: photo.fullImage,
          timestamp: photo.timestamp,
          processed: true
        }))
        console.log('已加载现有照片:', capturedPhotos.value.length, '张')
      }
    } catch (error) {
      console.error('加载现有照片失败:', error)
    }
  }
})

onUnmounted(() => {
  // 清理摄像头资源
  stopCamera()

  // 清理事件监听器
  document.removeEventListener('mousemove', handleCropFrameMouseMove)
  document.removeEventListener('mouseup', handleCropFrameMouseUp)
})
</script>

<style scoped>
.camera-capture {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: #000;
  display: flex;
  z-index: 1000;
  overflow: visible;
}

/* 返回按钮 - 左上角 */
.router-back-btn {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 48px;
  height: 48px;
  background: rgba(0, 0, 0, 0.6);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  transition: all 0.3s;
}

.router-back-btn:hover {
  background: rgba(0, 0, 0, 0.8);
  transform: scale(1.1);
}

.router-back-btn img {
  width: 24px;
  height: 24px;
  filter: brightness(0) invert(1);
}

/* 左侧区域：包含拍照模式选择和摄像头区域 */
.camera-left-section {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  overflow: visible;
}

/* 左侧拍照模式选择 - 绝对定位到摄像头区域左侧 */
.camera-sidebar {
  position: absolute;
  left: 360px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
}

.capture-modes {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.mode-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.mode-item:hover {
  background: rgba(255, 255, 255, 0.2);
}

.mode-item.active {
  background: rgba(64, 158, 255, 0.8);
  color: #fff;
}

.mode-icon {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mode-icon img {
  width: 24px;
  height: 24px;
  filter: brightness(0) invert(1);
}

.mode-text {
  font-size: 12px;
  font-weight: 500;
}

/* 中间摄像头区域 - 居中显示，使用相对定位容器 */
.camera-center {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: visible;
}

.camera-preview-area {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 800px;
  overflow: visible;
}

.camera-frame {
  width: 100%;
  max-width: 600px;
  aspect-ratio: 4/3;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
  position: relative;
}

.preview-content {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 模拟试卷内容 */
.paper-preview {
  width: 90%;
  height: 90%;
  background: #fff;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.paper-content {
  width: 100%;
  height: 100%;
  font-size: 12px;
  color: #333;
}

.paper-header {
  text-align: center;
  margin-bottom: 20px;
}

.paper-header h3 {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 5px 0;
}

.paper-header h4 {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
}

.question-section {
  margin-bottom: 15px;
}

.question-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.question-label {
  font-size: 12px;
}

.answer-box {
  width: 60px;
  height: 20px;
  border: 1px solid #333;
}

.question-content p {
  font-weight: 600;
  margin: 0 0 10px 0;
}

.calculation-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 15px;
}

.calc-item {
  font-size: 12px;
}

/* 摄像头视频样式 */
.camera-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 无摄像头时的提示信息 */
.no-camera-message {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  color: #fff;
}

.message-content {
  text-align: center;
  padding: 40px;
}

.camera-icon {
  font-size: 48px;
  margin-bottom: 20px;
  opacity: 0.6;
}

.message-content h3 {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 16px 0;
  color: #fff;
}

.message-content p {
  font-size: 14px;
  margin: 8px 0;
  color: rgba(255, 255, 255, 0.8);
  line-height: 1.5;
}

/* 拍照辅助线 */
.guide-lines {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 5;
}

.guide-line {
  position: absolute;
  background: rgba(255, 255, 255, 0.3);
}

.guide-line-h1 {
  top: 33.33%;
  left: 0;
  width: 100%;
  height: 1px;
}

.guide-line-h2 {
  top: 66.66%;
  left: 0;
  width: 100%;
  height: 1px;
}

.guide-line-v1 {
  left: 33.33%;
  top: 0;
  width: 1px;
  height: 100%;
}

.guide-line-v2 {
  left: 66.66%;
  top: 0;
  width: 1px;
  height: 100%;
}

/* 裁切覆盖层 */
.crop-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 20;
}

.crop-mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.6);
  /* 使用clip-path创建裁切区域内部透明的效果 */
  clip-path: polygon(0% 0%,
      0% 100%,
      var(--crop-left) 100%,
      var(--crop-left) var(--crop-top),
      var(--crop-right) var(--crop-top),
      var(--crop-right) var(--crop-bottom),
      var(--crop-left) var(--crop-bottom),
      var(--crop-left) 100%,
      100% 100%,
      100% 0%);
}

.crop-frame {
  position: absolute;
  border: 2px solid #409EFF;
  background: transparent;
  cursor: move;
}

.crop-corner {
  position: absolute;
  width: 12px;
  height: 12px;
  background: #409EFF;
  border: 2px solid #fff;
  border-radius: 50%;
  cursor: pointer;
}

.crop-corner-tl {
  top: -6px;
  left: -6px;
  cursor: nw-resize;
}

.crop-corner-tr {
  top: -6px;
  right: -6px;
  cursor: ne-resize;
}

.crop-corner-bl {
  bottom: -6px;
  left: -6px;
  cursor: sw-resize;
}

.crop-corner-br {
  bottom: -6px;
  right: -6px;
  cursor: se-resize;
}

.crop-actions {
  position: absolute;
  bottom: -50px;
  right: 0;
  display: flex;
  gap: 10px;
}

.crop-btn {
  width: 50px;
  height: 40px;
  border-radius: 8px;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: bold;
  transition: all 0.3s;
  background: #fff;
  color: #000;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.crop-cancel {
  background: #fff;
  color: #000;
}

.crop-cancel:hover {
  background: #f0f0f0;
  transform: scale(1.05);
}

.crop-confirm {
  background: #000;
  color: #fff;
}

.crop-confirm:hover {
  background: #333;
  transform: scale(1.05);
}

.crop-hint {
  position: absolute;
  bottom: -80px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 14px;
  text-align: center;
  background: rgba(0, 0, 0, 0.7);
  padding: 8px 16px;
  border-radius: 20px;
}

/* 底部控制按钮 - 绝对定位到摄像头区域下方 */
.camera-controls {
  position: absolute;
  bottom: 50px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 60px;
  z-index: 10;
}

.control-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  transition: all 0.3s;
}

.control-btn:hover {
  transform: translateY(-2px);
}

.control-btn img {
  width: 32px;
  height: 32px;
  filter: brightness(0) invert(1);
}

.control-btn span {
  font-size: 14px;
  font-weight: 500;
}

/* 拍照按钮特殊样式 */
.capture-btn {
  position: relative;
}

.capture-circle {
  width: 70px;
  height: 70px;
  border: 3px solid #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
}

.capture-inner {
  width: 50px;
  height: 50px;
  background: #fff;
  border-radius: 50%;
  transition: all 0.3s;
}

.capture-btn.capturing .capture-circle {
  transform: scale(1.1);
}

.capture-btn.capturing .capture-inner {
  transform: scale(0.8);
}

.capture-btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.capture-btn.disabled .capture-circle {
  border-color: #ccc;
}

.capture-btn.disabled .capture-inner {
  background: #ccc;
}

/* 右侧预览区域 - 相对定位覆盖层 */
.preview-sidebar {
  position: absolute;
  top: 0;
  right: 0;
  width: 120px;
  height: 100%;
  background: rgba(0, 0, 0, 0.8);
  padding: 20px 10px;
  display: flex;
  flex-direction: column;
  z-index: 15;
  overflow-y: auto;
  overflow-x: hidden;
}

/* 隐藏滚动条但保持滚动功能 */
.preview-sidebar::-webkit-scrollbar {
  display: none;
}

.preview-sidebar {
  -ms-overflow-style: none;
  /* IE and Edge */
  scrollbar-width: none;
  /* Firefox */
}

.preview-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.preview-item {
  position: relative;
  cursor: pointer;
}

.preview-item.active {
  /* 移除放大和蓝框效果，只保留基本的选中状态 */
  opacity: 0.8;
}

.preview-number {
  position: absolute;
  top: -12px;
  left: -10px;
  width: 19px;
  height: 18px;
  background: #409EFF;
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  z-index: 2;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.preview-delete {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 20px;
  height: 20px;
  background: rgba(128, 128, 128, 0.8);
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  z-index: 2;
  cursor: pointer;
  transition: all 0.3s;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.preview-delete:hover {
  background: rgba(128, 128, 128, 1);
  transform: scale(1.1);
}

.preview-image {
  width: 80px;
  height: 60px;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
}

.preview-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 模拟白纸缩略图 */
.paper-thumbnail {
  width: 100%;
  height: 100%;
  padding: 8px;
  background: #fff;
}

.thumbnail-content {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.thumbnail-header {
  font-size: 8px;
  font-weight: 600;
  text-align: center;
  margin-bottom: 4px;
  color: #333;
}

.thumbnail-lines {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.line {
  height: 1px;
  background: #ddd;
  width: 100%;
}

/* 添加更多按钮 */
.add-more-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 15px 10px;
  border: 2px dashed rgba(255, 255, 255, 0.5);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
  color: #fff;
}

.add-more-btn:hover {
  border-color: #409EFF;
  background: rgba(64, 158, 255, 0.1);
}

.add-icon {
  width: 30px;
  height: 30px;
  border: 2px solid #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: 600;
}

.add-more-btn span {
  font-size: 12px;
}

.add-more-btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  border-color: rgba(255, 255, 255, 0.3);
}

.add-more-btn.disabled:hover {
  border-color: rgba(255, 255, 255, 0.3);
  background: transparent;
}

.add-more-btn.disabled .add-icon {
  border-color: rgba(255, 255, 255, 0.5);
}

/* iPad平板端优化 - 移除移动端响应式设计，专注iPad适配 */

/* 完成按钮样式 */
.complete-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px 20px;
  background: #409EFF;
  color: #fff;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
  margin-top: 10px;
}

.complete-btn:hover {
  background: #66b1ff;
  transform: translateY(-1px);
}

.complete-btn span {
  font-size: 14px;
  font-weight: 600;
}

/* 文件导入弹窗样式 */
.file-import-dialog {
  padding: 20px 0;
}

.upload-file-section {
  margin-bottom: 20px;
}

.upload-file-label {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 12px;
}

.upload-file-label::before {
  content: "*";
  color: #f56c6c;
  margin-right: 4px;
}

.upload-file-area {
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  background: #fafafa;
  transition: all 0.3s;
}

.upload-file-area:hover {
  border-color: #409EFF;
  background: #f0f9ff;
}

.upload-file-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  gap: 16px;
}

.upload-file-icon {
  color: #c0c4cc;
}

.upload-file-text {
  text-align: center;
}

.upload-main-text {
  font-size: 14px;
  color: #606266;
  margin-bottom: 8px;
}

.upload-sub-text {
  font-size: 12px;
  color: #909399;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* Element Plus 组件样式覆盖 */
:deep(.el-dialog__header) {
  padding: 20px 20px 10px;
  border-bottom: 1px solid #f0f0f0;
}

:deep(.el-dialog__title) {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

:deep(.el-upload-dragger) {
  border: none;
  background: transparent;
  width: 100%;
  height: auto;
}

:deep(.el-upload-dragger:hover) {
  border: none;
  background: transparent;
}
</style>